/**
 * Copyright (c) 快宝网络 kuaidihelp.com Co., Ltd. All Rights Reserved 禁止外泄以及用于其它的商业用途
 */

import { isFunction } from 'lodash';
import type { LegacyRef } from 'react';
import React, { useEffect, useRef, useState } from 'react';
import KbAnimate from './animate';
import { useObserverDom } from './_utils/';
import { ObserverContext } from './_utils/context';
import type { ObserverProps } from './_utils/types';

const Index: React.FC<ObserverProps> = (props) => {
  const [show, setShow] = useState(false);
  const {
    type,
    children,
    onChange,
    elementID,
    rootRef,
    opts,
    oneWay,
    intersectionRatio: hopeIntersectionRatio = 0.3,
    ...rest
  } = props;
  const actionRef = useRef<HTMLDivElement>();
  const queryRef = useRef<HTMLDivElement>();

  useEffect(() => {
    if (elementID) {
      const node = document.querySelector(`#${elementID}`) as HTMLDivElement;
      if (node) {
        queryRef.current = node;
      } else {
        console.error(`[animate-elementID]: ${elementID}元素找不到`);
      }
      console.warn('[animate]: elementID对应元素不会触发动画');
    }
  }, [elementID]);

  useObserverDom(
    (obOpts) => {
      if (obOpts) {
        const { entries, observer, node } = obOpts;
        const [{ isIntersecting, intersectionRatio }] = entries || [];
        if (!isIntersecting) {
          setShow(false);
        } else if (isIntersecting && intersectionRatio >= hopeIntersectionRatio) {
          setShow(true);
          if (oneWay) {
            // 单次动画，执行完毕后终止监听；
            observer.unobserve(node);
            observer.disconnect();
          }
        }
      } else {
        setShow(true);
      }
      if (isFunction(onChange)) {
        onChange(obOpts);
      }
    },
    { rootRef, actionRef, queryRef, opts, intersectionRatio: hopeIntersectionRatio },
  );

  // 传入type的，自动包裹动画组件；否则需要用户手动包裹；
  const observerElement = type ? <KbAnimate>{children}</KbAnimate> : children;

  return (
    <ObserverContext.Provider value={{ show, type, elementID, ...rest }}>
      {elementID ? (
        observerElement
      ) : (
        <div className='kb-animate-observer' ref={actionRef as LegacyRef<HTMLDivElement>}>
          {observerElement}
        </div>
      )}
    </ObserverContext.Provider>
  );
};

Index.defaultProps = {
  oneWay: true,
};

export default Index;
